package cui

import (
	"fmt"
	"strings"

	"gitee.com/xuender/oils/ids"
	"gitee.com/xuender/oils/logs"
	"gitee.com/xuender/pp/pb"
	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
)

// UserData 用户数据.
type UserData struct {
	app *tview.Application
	// 用户的输入框
	input *tview.InputField
	// 用户的显示区域
	display *tview.TextView
	// 历史输入
	history *tview.List
	// 显示区域
	flex *tview.Flex
	// 用户在列表中的位置
	index int
	// 用户热键
	key byte
	// 需要读取的消息
	Msgs int
	// 用户
	user *pb.User
	s    *Service
}

// NewUserData 新建用户数据.
func NewUserData(
	user *pb.User,
	app *tview.Application,
	key byte,
	s *Service,
) *UserData {
	id := ids.Bytes(user.ID)
	display := tview.NewTextView().
		SetDynamicColors(true).
		SetRegions(true).
		SetWordWrap(true)
	flex := tview.NewFlex().
		SetDirection(tview.FlexRow).
		AddItem(display, 0, 3, false)
	input := tview.NewInputField().
		SetLabel("对 [ " + user.Nick + " ] 说: ")
	inputFrame := tview.NewFrame(input).
		SetBorders(0, 1, 1, 1, 2, 2).
		AddText("输入区", true, tview.AlignLeft, tcell.ColorGold)
	rightGrid := tview.NewGrid().
		SetColumns(0).SetRows(0, 4)
	history := tview.NewList().
		ShowSecondaryText(false)

	rightGrid.SetBorder(false)
	rightGrid.AddItem(flex, 0, 0, 1, 1, 0, 0, false)
	rightGrid.AddItem(inputFrame, 1, 0, 1, 1, 0, 0, true)
	s.pages.AddPage(id.String(), rightGrid, true, false)

	ud := &UserData{
		s:       s,
		app:     app,
		key:     key,
		display: display,
		input:   input,
		history: history,
		flex:    flex,
		user:    user,
		index:   s.list.GetItemCount(),
	}

	input.SetDoneFunc(ud.inputDone)
	s.list.AddItem(user.Nick, ud.secondary(), 0, ud.listSelect)

	return ud
}

func (u *UserData) listSelect() {
	logs.Debug("选择用户", u.user.Nick)
	id := ids.Bytes(u.user.ID)
	u.s.SelectUser(id)
}

func (u *UserData) inputDone(key tcell.Key) {
	if key == tcell.KeyDown || key == tcell.KeyUp {
		u.history.SetCurrentItem(u.history.GetItemCount() - 1)
		u.flex.AddItem(u.history, 0, 1, false)
		u.app.SetFocus(u.history)

		return
	}

	text := u.input.GetText()
	if key != tcell.KeyEnter || text == "" {
		return
	}

	msg := &pb.Msg{
		To:   u.user.ID,
		From: u.s.me.ID,
		Type: pb.MsgType_Text,
		Data: []byte(text),
	}

	u.s.send(msg)
	u.input.SetText("")
	u.history.AddItem(text, "", 0, func() {
		u.flex.RemoveItem(u.history)
		u.input.SetText(text)
		u.app.SetFocus(u.input)
	})

	if max := 30; u.history.GetItemCount() > max {
		u.history.RemoveItem(0)
	}
}

func (u *UserData) secondary() string {
	var b strings.Builder

	if u.key > 0 {
		b.WriteString("热键: CTRL+")
		b.WriteByte(u.key)
	} else {
		b.WriteString("热键无")
	}

	if u.Msgs > 0 {
		b.WriteString(fmt.Sprintf(" (%d)", u.Msgs))
	}

	return b.String()
}

func (u *UserData) Nick() string {
	return u.user.Nick
}
